package com.nnnu.orange.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nnnu.orange.constant.BookStatusConstants;
import com.nnnu.orange.constant.MessageConstants;
import com.nnnu.orange.exception.ObjectException;
import com.nnnu.orange.exception.ObjectNullException;
import com.nnnu.orange.pojo.dto.BookDto;
import com.nnnu.orange.pojo.dto.BooksQueryDto;
import com.nnnu.orange.pojo.entity.Books;
import com.nnnu.orange.mapper.BooksMapper;
import com.nnnu.orange.pojo.vo.BooksInfoVo;
import com.nnnu.orange.result.PageResult;
import com.nnnu.orange.service.IBooksService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 存储每本图书的详细信息 服务实现类
 * </p>
 *
 * @author zk
 * @since 2024-11-07
 */
@Service
@Transactional
public class BooksServiceImpl extends ServiceImpl<BooksMapper, Books> implements IBooksService {
    /**
     * 分页查询图书列表
     *
     * @param queryDto dto
     * @return 分页图书列表
     */
    @Override
    public PageResult<BooksInfoVo> listBooks(@NotNull BooksQueryDto queryDto) {
        // 判断是否传递了分页参数，如果没有传递则查询所有数据
        boolean isPagination = queryDto.getPageNum() != null && queryDto.getPageSize() != null
                && queryDto.getPageNum() > 0 && queryDto.getPageSize() > 0;

        Page<BooksInfoVo> booksInfoVoPage;

        if (isPagination) {
            // 有分页参数，正常分页查询
            Page<BooksInfoVo> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
            booksInfoVoPage = baseMapper.selectBooksInfoPage(page, queryDto);
        } else {
            // 无分页参数，查询所有数据
            booksInfoVoPage = new Page<>(1, Integer.MAX_VALUE);  // 使用最大值获取所有数据
            booksInfoVoPage = baseMapper.selectBooksInfoPage(booksInfoVoPage, queryDto);
        }

        return new PageResult<>(booksInfoVoPage.getTotal(), booksInfoVoPage.getRecords());
    }


    /**
     * 新增图书
     *
     * @param bookDto dto
     * @return 是否添加成功
     */
    @Override
    public Boolean save(BookDto bookDto) {
        Books books = BeanUtil.copyProperties(bookDto, Books.class);
        books.setStatus(BookStatusConstants.PENDING_SHELF);
        books.setAddedDate(LocalDateTime.now());
        return save(books);
    }

    /**
     * 修改图书信息
     *
     * @param bookDto 图书dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(@NotNull BookDto bookDto) {

        Books currentBook = baseMapper.selectById(bookDto.getBookId());
        if (currentBook == null) {
            throw new ObjectException("图书不存在，无法更新");
        }


        if (currentBook.getVersion() == null) {
            throw new ObjectException("图书版本号未初始化，无法更新");
        }
        BeanUtil.copyProperties(bookDto, currentBook);

        int updateResult = baseMapper.updateById(currentBook);
        if (updateResult == 0) {
            throw new ObjectException("更新失败，可能是版本冲突，请重试");
        }
    }

    /**
     * 批量删除图书
     *
     * @param ids 图书id列表
     * @return 是否删除成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ObjectNullException(MessageConstants.NULL);
        }
        List<Books> booksList = baseMapper.selectList(new LambdaQueryWrapper<Books>()
                .select(Books::getBookId, Books::getStatus)
                .in(Books::getBookId, ids)
                .in(Books::getStatus,
                        BookStatusConstants.ON_SHELF,
                        BookStatusConstants.CHECKED_OUT,
                        BookStatusConstants.RESERVED,
                        BookStatusConstants.UNDER_REPAIR));
        List<String> messages = booksList.stream()
                .map(book -> "图书id " + book.getBookId() + " 可能存在上架中")
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(messages)) {
            throw new ObjectNullException(MessageConstants.DELETE_FAILED + ": " + String.join(", ", messages));
        }
        // 批量删除
        return removeByIds(ids);
    }

    /**
     * 批量插入图书
     *
     * @param booksList 图书列表
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchInsert(List<Books> booksList) {
        if (CollectionUtils.isEmpty(booksList)) {
            throw new RuntimeException("导入数据为空");
        }
        // 批量插入数据库
        saveBatch(booksList);
    }
}
